package git

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
)

var RootPath = "d:/GitClone/"

type Data struct {
	serviceName  string
	git          string
	branchDev    string
	branchTest   string
	branchOnline string
	serviceType  int
	code         string
}

func dirExists(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

func copyDirectory(source string, destination string) error {
	fileInfo, err := os.Stat(source)
	if err != nil {
		return err
	}

	err = os.MkdirAll(destination, fileInfo.Mode())
	if err != nil {
		return err
	}

	entries, err := os.ReadDir(source)
	if err != nil {
		return err
	}

	for _, entry := range entries {
		sourcePath := filepath.Join(source, entry.Name())
		destinationPath := filepath.Join(destination, entry.Name())

		if entry.IsDir() {
			err = copyDirectory(sourcePath, destinationPath)
			if err != nil {
				return err
			}
		} else {
			err = copyFile(sourcePath, destinationPath)
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func copyFile(source string, destination string) error {
	sourceFile, err := os.Open(source)
	if err != nil {
		return err
	}
	defer sourceFile.Close()

	destinationFile, err := os.Create(destination)
	if err != nil {
		return err
	}
	defer destinationFile.Close()

	_, err = io.Copy(destinationFile, sourceFile)
	if err != nil {
		return err
	}

	return nil
}

func replaceValueInFile(filePath string, oldValue string, newValue string) error {
	// Read the file content
	content, err := ioutil.ReadFile(filePath)
	if err != nil {
		return err
	}

	// Perform the replacement
	newContent := strings.ReplaceAll(string(content), oldValue, newValue)

	// Write the modified content back to the file
	err = ioutil.WriteFile(filePath, []byte(newContent), 0644)
	if err != nil {
		return err
	}

	return nil
}

func GetGit() ([]Data, error) {
	// 连接字符串
	db, err := sql.Open("mysql", "root:fJJuK8kWCGXRf7@tcp(192.168.1.100:23306)/huadao_yunwei")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 检查连接是否成功
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}

	// 执行查询
	//sqltext := "SELECT b.name,git,branch_dev,branch_test,branch_online,b.type,c.code FROM git a join servicename b on a.sn_id=b.id join businessline c on a.bl_id=c.id where a.id not in (60,74,75,76,90,91) and a.id=66"
	sqltext := "SELECT  b.name,git,branch_dev,branch_test,branch_online,b.type,c.code FROM git a join servicename b on a.sn_id=b.id join businessline c on a.bl_id=c.id where a.id not in (60,74,75,76,90,91) and code='gmp' and type=2"
	rows, err := db.Query(sqltext)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	// 处理查询结果
	var data []Data
	for rows.Next() {
		var d Data
		err := rows.Scan(&d.serviceName, &d.git, &d.branchDev, &d.branchTest, &d.branchOnline, &d.serviceType, &d.code)
		if err != nil {
			log.Fatal(err)
		}
		data = append(data, d)
	}

	if err = rows.Err(); err != nil {
		return nil, err
	}

	return data, nil
}

func GetClone(GitPath string, git string) {
	cloneArgs := []string{"clone", git, GitPath}
	// 创建命令
	cmd := exec.Command("git", cloneArgs...)
	// 设置命令的输出和错误输出
	//cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// 执行命令
	err := cmd.Run()
	if err != nil {
		fmt.Printf("Failed to execute git clone: %s\n", err)
		return
	}

	fmt.Println("Git clone completed successfully")
}

func SwitchBranch(GitPath string, branch string) {
	// 设置切换分支命令的工作目录
	err := os.Chdir(GitPath)
	// 切换分支命令
	checkoutArgs := []string{"checkout", branch}
	// 创建切换分支的命令
	checkoutCmd := exec.Command("git", checkoutArgs...)

	// 执行切换分支命令
	err = checkoutCmd.Run()
	if err != nil {
		fmt.Printf(GitPath+" Failed to execute git checkout: %s\n", err)
		return
	}

	cmd := exec.Command("git", "pull")
	err = cmd.Run()
	if err != nil {
		fmt.Println(GitPath+"Error:", err)
		return
	}

	fmt.Println("Git branch " + branch + " switched successfully")
}

func GitCommit(GitPath string) {
	err := os.Chdir(GitPath)

	cmd := exec.Command("git", "add", ".")
	err = cmd.Run()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Files added to staging area.")

	cmd = exec.Command("git", "commit", "-m", "update by xiachen golang script")
	err = cmd.Run()
	if err != nil {
		fmt.Printf("Error:", err)
		return
	}
	fmt.Println("Committed changes.")

	cmd = exec.Command("git", "push")
	err = cmd.Run()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Pushed changes to remote repository.")
}

func findFiles(root string, pattern *regexp.Regexp) ([]string, error) {
	var matches []string
	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		if pattern.MatchString(path) {
			matches = append(matches, path)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return matches, nil
}

func GitChange(d Data) {
	var GitPath = RootPath + d.code + "/" + d.serviceName
	if !dirExists(GitPath) {
		GetClone(GitPath, d.git)
	}

	if d.code == "corp" {
		/*
			// 切换分支
			SwitchBranch(GitPath, d.branchTest)



				// 查找所有appsettings.json
				pattern := regexp.MustCompile(`appsettings.*json`)
				matches, err := findFiles(GitPath, pattern)
				if err != nil {
					fmt.Println("Error:", err)
					return
				}
				for _, match := range matches {
					fmt.Println(match)
					//修改内容
					//redis
					replaceValueInFile(match, "dev-redis", "dev.redis.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31101", "dev.redis.huadaocart.corp")
					replaceValueInFile(match, "test-redis", "test.redis.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31102", "test.redis.huadaocart.corp")
					//mongodb
					replaceValueInFile(match, "dev-mongodb", "dev.mongodb.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31201", "dev.mongodb.huadaocart.corp")
					replaceValueInFile(match, "test-mongodb", "test.mongodb.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31202", "test.mongodb.huadaocart.corp")
					//rabbitmq
					replaceValueInFile(match, "dev-rabbitmq", "dev.rabbitmq.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31301", "dev.rabbitmq.huadaocart.corp")
					replaceValueInFile(match, "test-rabbitmq", "test.rabbitmq.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31302", "test.rabbitmq.huadaocart.corp")
					//minio
					replaceValueInFile(match, "dev-minio", "dev.minio.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31401", "dev.minio.huadaocart.corp")
					replaceValueInFile(match, "test-minio", "test.minio.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31402", "test.minio.huadaocart.corp")
					//mssql
					replaceValueInFile(match, "dev.mssql.huadaopharma", "dev.mssql.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.185", "dev.mssql.huadaocart.corp")
					replaceValueInFile(match, "test.mssql.huadaopharma", "test.mssql.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.186", "test.mssql.huadaocart.corp")

				}

				// 查找所有nlog.config
				pattern = regexp.MustCompile(`nlog.*config`)
				matches, err = findFiles(GitPath, pattern)
				if err != nil {
					fmt.Println("Error:", err)
					return
				}
				for _, match := range matches {
					fmt.Println(match)
					//修改内容
					//mongodb
					replaceValueInFile(match, "dev-mongodb", "dev.mongodb.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31201", "dev.mongodb.huadaocart.corp")
					replaceValueInFile(match, "test-mongodb", "test.mongodb.huadaocart.corp")
					replaceValueInFile(match, "192.168.1.171:31202", "test.mongodb.huadaocart.corp")
				}
				GitCommit(GitPath)
				// 修改DEV环境配置结束

		*/
	}

	if d.code == "gmp" {
		// 切换分支
		SwitchBranch(GitPath, d.branchTest)

		// 查找所有appsettings.json
		pattern := regexp.MustCompile(`appsettings.*json`)
		matches, err := findFiles(GitPath, pattern)
		if err != nil {
			fmt.Println("Error:", err)
			return
		}
		for _, match := range matches {
			fmt.Println(match)
			//修改内容
			//redis
			replaceValueInFile(match, "dev-redis", "dev.redis.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31101", "dev.redis.huadaocart.gmp")
			replaceValueInFile(match, "test-redis", "test.redis.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31102", "test.redis.huadaocart.gmp")
			//mongodb
			replaceValueInFile(match, "dev-mongodb", "dev.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31201", "dev.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "test-mongodb", "test.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31202", "test.mongodb.huadaocart.gmp")
			//rabbitmq
			replaceValueInFile(match, "dev-rabbitmq", "dev.rabbitmq.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31301", "dev.rabbitmq.huadaocart.gmp")
			replaceValueInFile(match, "test-rabbitmq", "test.rabbitmq.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31302", "test.rabbitmq.huadaocart.gmp")
			//minio
			replaceValueInFile(match, "dev-minio", "dev.minio.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31401", "dev.minio.huadaocart.gmp:9000")
			replaceValueInFile(match, "test-minio", "test.minio.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31402", "test.minio.huadaocart.gmp:9000 ")
			//mssql
			replaceValueInFile(match, "dev-gmp.mssql.huadaopharma", "dev.mssql.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.125", "dev.mssql.huadaocart.gmp")
			replaceValueInFile(match, "test-gmp.mssql.huadaopharma", "test.mssql.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.126", "test.mssql.huadaocart.gmp")

		}

		// 查找所有nlog.config
		pattern = regexp.MustCompile(`nlog.*config`)
		matches, err = findFiles(GitPath, pattern)
		if err != nil {
			fmt.Println("Error:", err)
			return
		}
		for _, match := range matches {
			fmt.Println(match)
			//修改内容
			//mongodb
			replaceValueInFile(match, "dev-mongodb", "dev.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31201", "dev.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "test-mongodb", "test.mongodb.huadaocart.gmp")
			replaceValueInFile(match, "192.168.1.101:31202", "test.mongodb.huadaocart.gmp")
		}
		GitCommit(GitPath)
		// 修改环境配置结束

	}
}

func ProcessGit(d Data) {
	var GitPath = RootPath + d.code + "/" + d.serviceName
	var K8sPath = RootPath + "k8sconfig" + "/" + d.code + "/" + d.serviceName
	var TempPath = RootPath + "templates/" + d.code

	if !dirExists(GitPath) {
		GetClone(GitPath, d.git)
	}

	if !dirExists(K8sPath) {
		os.Mkdir(K8sPath, 0755)
	}

	//master分支操作
	SwitchBranch(GitPath, "master")
	source := GitPath + "/deployment"
	destination := K8sPath
	copyDirectory(source, destination)
	fmt.Println("Directory:deployment copied")

	sourceFile := GitPath + "/Jenkinsfile"
	destinationFile := K8sPath + "/Jenkinsfile"
	copyFile(sourceFile, destinationFile)
	fmt.Println("file:Jenkinsfile copied")

	if d.serviceType == 2 {
		sourceFile := GitPath + "/appsettings.Production.json"
		destinationFile := K8sPath + "/appsettings.Production.json"
		err := copyFile(sourceFile, destinationFile)
		if err == nil {
			fmt.Println("file:appsettings.Production.json copied")
		}

		sourceFile = GitPath + "/nlog.Production.config"
		destinationFile = K8sPath + "/nlog.Production.config"
		err = copyFile(sourceFile, destinationFile)
		if err == nil {
			fmt.Println("file:nlog.Production.config copied")
		}

	}

	//online分支操作
	SwitchBranch(GitPath, d.branchOnline)
	source = GitPath + "/deployment/overlays/online"
	destination = K8sPath + "/overlays/online"
	copyDirectory(source, destination)
	fmt.Println("Directory:deployment_online copied")

	if d.serviceType == 2 {
		sourceFile := GitPath + "/appsettings.Online.json"
		destinationFile := K8sPath + "/appsettings.Online.json"
		err := copyFile(sourceFile, destinationFile)
		if err == nil {
			fmt.Println("file:appsettings.Online.json copied")
		}

		sourceFile = GitPath + "/nlog.Online.config"
		destinationFile = K8sPath + "/nlog.Online.config"
		err = copyFile(sourceFile, destinationFile)
		if err == nil {
			fmt.Println("file:nlog.Online.config copied")
		}

	}

	//test分支操作
	SwitchBranch(GitPath, d.branchTest)
	source = GitPath + "/deployment/overlays/test"
	destination = K8sPath + "/overlays/test"
	copyDirectory(source, destination)
	fmt.Println("Directory:deployment_test copied")

	//dev分支操作
	SwitchBranch(GitPath, d.branchDev)
	source = GitPath + "/deployment/overlays/dev"
	destination = K8sPath + "/overlays/dev"
	copyDirectory(source, destination)
	fmt.Println("Directory:deployment_dev copied")

	//copy ui pipeline file
	if d.serviceType == 1 {

		sourceFile := TempPath + "/dev-ui.pipeline"
		destinationFile := K8sPath + "/dev-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-ui", d.serviceName)
		replaceValueInFile(destinationFile, "template-git", d.git)
		replaceValueInFile(destinationFile, "template-branchDev", d.branchDev)

		sourceFile = TempPath + "/test-ui.pipeline"
		destinationFile = K8sPath + "/test-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-ui", d.serviceName)
		replaceValueInFile(destinationFile, "template-git", d.git)
		replaceValueInFile(destinationFile, "template-branchTest", d.branchTest)

		sourceFile = TempPath + "/online-ui.pipeline"
		destinationFile = K8sPath + "/online-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-ui", d.serviceName)

		sourceFile = TempPath + "/prod-ui.pipeline"
		destinationFile = K8sPath + "/prod-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-ui", d.serviceName)

		fmt.Println("UI Pipeline template files copied")
	}

	//copy api pipeline file
	if d.serviceType == 2 {

		sourceFile := TempPath + "/dev-api.pipeline"
		destinationFile := K8sPath + "/dev-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-api", d.serviceName)
		replaceValueInFile(destinationFile, "template-git", d.git)
		replaceValueInFile(destinationFile, "template-branchDev", d.branchDev)

		sourceFile = TempPath + "/test-api.pipeline"
		destinationFile = K8sPath + "/test-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-api", d.serviceName)
		replaceValueInFile(destinationFile, "template-git", d.git)
		replaceValueInFile(destinationFile, "template-branchTest", d.branchTest)

		sourceFile = TempPath + "/online-api.pipeline"
		destinationFile = K8sPath + "/online-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-api", d.serviceName)

		sourceFile = TempPath + "/prod-api.pipeline"
		destinationFile = K8sPath + "/prod-" + d.serviceName + ".pipeline"
		copyFile(sourceFile, destinationFile)
		replaceValueInFile(destinationFile, "template-api", d.serviceName)

		fmt.Println("API Pipeline template files copied")
	}

}

//func main() {
//
//	data, err := GetGit()
//
//	if err != nil {
//		// Handle the error
//	}
//
//	for _, d := range data {
//		ProcessGit(d)
//		// fmt.Println()
//	}
//
//	//fmt.Println(accessKey79)
//}
